package com.example.logisticsingle.authorization;


import com.example.logisticsingle.String.StringUtils;
import com.example.logisticsingle.utils.RedisUtils;
import org.springframework.security.web.authentication.rememberme.PersistentRememberMeToken;
import org.springframework.security.web.authentication.rememberme.PersistentTokenRepository;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 *  	记住我处理功能
 *
 */
@Component
public class RememberMeHandler implements PersistentTokenRepository {
    /**
     * token有效时间15天
     */
    private static final Long TOKEN_VALID_DAYS = 15L;

    @Override
    public void createNewToken(PersistentRememberMeToken token) {
        String key = generateTokenKey(token.getSeries());
        Map<String,String> map = new HashMap<>(8);
        map.put("username", token.getUsername());
        map.put("tokenValue", token.getTokenValue());
        map.put("date", String.valueOf(token.getDate().getTime()));
        RedisUtils.putALL(key, map, TOKEN_VALID_DAYS, TimeUnit.DAYS);
        saveUsernameAndSeries(token.getUsername(), token.getSeries());
    }

    @Override
    public void updateToken(String series, String tokenValue, Date lastUsed) {
        String key = generateTokenKey(series);
        Boolean hasSeries = RedisUtils.hasKey(key);
        if(hasSeries==null || !hasSeries){
            return;
        }
        Map<String,String> map = new HashMap<>(4);
        map.put("tokenValue", tokenValue);
        map.put("date", String.valueOf(lastUsed.getTime()));
        RedisUtils.putALL(key, map, TOKEN_VALID_DAYS, TimeUnit.DAYS);
        String username = (String) RedisUtils.get(generateUsernameAndSeriesKey(series));
        saveUsernameAndSeries(username, series);
    }

    @Override
    public PersistentRememberMeToken getTokenForSeries(String seriesId) {
        String key = generateTokenKey(seriesId);
        Map<Object, Object> hashKeyValues = RedisUtils.entries(key);
        if(hashKeyValues == null) return null;
        Object username = hashKeyValues.get("username");
        Object tokenValue = hashKeyValues.get("tokenValue");
        Object date = hashKeyValues.get("date");
        if (null == username || null == tokenValue || null == date) {
            return null;
        }
        long timestamp = Long.valueOf(String.valueOf(date));
        Date time = new Date(timestamp);
        return new PersistentRememberMeToken(String.valueOf(username), seriesId, String.valueOf(tokenValue), time);
    }

    @Override
    public void removeUserTokens(String username) {
        String key = generateUsernameAndSeriesKey(username);
        String series = (String) RedisUtils.get(key);
        if (StringUtils.isNull(series)){
            return;
        }
        RedisUtils.del(generateTokenKey(series),generateUsernameAndSeriesKey(username),generateUsernameAndSeriesKey(series));
    }
    /**
     * 生成的相关信息保存在Redis中
     * @param username
     * @param series
     */
    private void saveUsernameAndSeries(String username, String series){
        RedisUtils.set(generateUsernameAndSeriesKey(username),series,TOKEN_VALID_DAYS*2, TimeUnit.DAYS);
        RedisUtils.set(generateUsernameAndSeriesKey(series),username,TOKEN_VALID_DAYS*2,TimeUnit.DAYS);
    }
    /**
     * 生成key
     * @param usernameOrSeries
     * @return
     */
    private String generateUsernameAndSeriesKey(String usernameOrSeries) {
        return "iam:sso:rememberMe:"+usernameOrSeries;
    }
    /**
     * 生成token key
     * @param series
     * @return
     */
    private String generateTokenKey(String series) {
        return "iam:sso:rememberMe:token:" + series;
    }

}
